package com.dabai.markdownq.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.dabai.dbutils.qrcode.QRCodeUtils;
import com.dabai.dbutils.utils.DabaiUtils;
import com.dabai.dbutils.utils.DateUtils;
import com.dabai.dbutils.utils.FileUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;

import io.noties.markwon.AbstractMarkwonPlugin;
import io.noties.markwon.Markwon;
import io.noties.markwon.MarkwonConfiguration;
import io.noties.markwon.core.MarkwonTheme;
import io.noties.markwon.ext.latex.JLatexMathPlugin;
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
import io.noties.markwon.ext.tables.TableAwareMovementMethod;
import io.noties.markwon.ext.tables.TablePlugin;
import io.noties.markwon.ext.tasklist.TaskListPlugin;
import io.noties.markwon.html.HtmlPlugin;
import io.noties.markwon.image.ImagesPlugin;
import io.noties.markwon.image.file.FileSchemeHandler;
import io.noties.markwon.image.gif.GifMediaDecoder;
import io.noties.markwon.image.glide.GlideImagesPlugin;
import io.noties.markwon.image.svg.SvgMediaDecoder;
import io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;
import io.noties.markwon.linkify.LinkifyPlugin;
import io.noties.markwon.movement.MovementMethodPlugin;

/**
 * Description : Other
 * 本类最后会整合进DBA
 *
 * @author BAI
 */
public class OtherUtils {


    /**
     * 规则是否合法
     *
     * @param pattern 模式
     * @return boolean
     */
    @SuppressLint("SimpleDateFormat")
    public static boolean legalRules(String pattern) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            sdf.format(new Date());
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    public static void copyDir(String source, String dest, boolean coverCopy) throws Exception {
        File path1 = new File(source);
        File path2 = new File(dest);

        // 如果源目录不存在,那就不用复制了,
        if (path1.exists()) {
            // Create destination folder,如果目标目录不存在,就创建目标目录,因为没有目录文件复制不过去的
            if (!path2.exists()) {
                path2.mkdirs();
            }

            // 取得源目录下面的所有文件和文件夹
            File[] items = path1.listFiles();

            // 取得所有文件和文件夹之后,遍历处理,如果是文件,就复制文件,如果是文件夹,则递归文件夹下面的文件和文件夹

            for (File item : items) {
                // 如果是文件才进行复制
                if (item.isFile()) {
                    File tagFile = new File(path2 + File.separator + item.getName());
                    if (tagFile.exists()) {
                        tagFile = new File(path2 + File.separator + DateUtils.getNowTime("hhmmss") + "_" + item.getName());
                    }
                    // 输入输出流的两个常用构造函数,其中在用来了一个字段File.separator,先用输入流读取文件,然后用输出流写文件到目标位置,完成复制功能
                    copyFile(item, tagFile, coverCopy);
                }
                // 如果是文件夹,递归文件夹
                else {
                    copyDir(item.getPath(), path2 + File.separator + item.getName(), coverCopy);
                }
            }
        } else {
            throw new Exception("源路径：[" + source + "] 不存在...");
        }
    }


    public static boolean copyFile(File source, File dest, boolean coverCopy) {

        //是否覆盖复制
        if (!coverCopy) {
            if (dest.exists()) {
                return false;
            }
        }

        try {
            if (!source.exists()) {
                return false;
            }
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            FileChannel inputChannel = null;
            FileChannel outputChannel = null;
            try {
                inputChannel = new FileInputStream(source).getChannel();
                outputChannel = new FileOutputStream(dest).getChannel();
                outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
                return true;
            } finally {
                inputChannel.close();
                outputChannel.close();
            }
        } catch (IOException e) {
            return false;
        }
    }


    /**
     * 解析MD内容并显示到 view
     *
     * @param context  上下文
     * @param textView 文本视图
     * @param content  内容
     */
    public static void parseMd(Context context, TextView textView, String content) {

        Markwon markwon = Markwon.builder(context)
                .usePlugin(TaskListPlugin.create(context))
                .usePlugin(HtmlPlugin.create())
                .usePlugin(LinkifyPlugin.create())
                .usePlugin(ImagesPlugin.create(plugin -> {
                    // uses Resources.getSystem()
                    plugin.addMediaDecoder(SvgMediaDecoder.create());

                    plugin.addSchemeHandler(FileSchemeHandler.create());
                    plugin.addSchemeHandler(FileSchemeHandler.createWithAssets(context));
                    plugin.addMediaDecoder(GifMediaDecoder.create(true));

                 //   plugin.placeholderProvider(drawable -> context.getResources().getDrawable(R.drawable.brvah_sample_footer_loading));
                }))
                .usePlugin(GlideImagesPlugin.create(context))
                .usePlugin(StrikethroughPlugin.create())
                .usePlugin(MarkwonInlineParserPlugin.create())
                .usePlugin(JLatexMathPlugin.create(textView.getTextSize(), builder -> {
                    // ENABLE inlines
                    builder.inlinesEnabled(true);
                    builder.blocksLegacy(true);
                    builder.blocksEnabled(true);
                    builder.errorHandler((latex, error) -> null);
                    builder.executorService(Executors.newCachedThreadPool());
                }))
                .usePlugin(MovementMethodPlugin.create(TableAwareMovementMethod.create()))
                .usePlugin(TablePlugin.create(builder ->
                        builder
                                .tableBorderColor(Color.GRAY)
                                .tableBorderWidth(5)
                                .tableCellPadding(10)
                ))
                .usePlugin(new AbstractMarkwonPlugin() {
                    @Override
                    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {

                        builder.linkColor(Color.BLUE)
                                .codeBlockTextColor(Color.WHITE)
                                .codeTextColor(Color.parseColor("#D32F2F"))
                                //代码块背景色
                                .codeBlockBackgroundColor(Color.parseColor("#424242"))
                                //单行代码背景色
                                .codeBackgroundColor(Color.parseColor("#FBE9E7"))
                                .codeTypeface(Typeface.MONOSPACE)
                                .isLinkUnderlined(true);

                    }
                    @Override
                    public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
                        builder.linkResolver((view, link) -> {

                            new MaterialAlertDialogBuilder(context).setTitle("提示")
                                    .setMessage("是否允许打开外部链接?")
                                    .setPositiveButton("允许", (dialog, which) -> DabaiUtils.openLink(context,link)).setNeutralButton("取消",null)
                                    .show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.Animation_AppCompat_DropDownUp);

                        });
                    }
                })
                .build();
        markwon.setMarkdown(textView, content + '\u3000');

    }


    /**
     * MD文本内容转义到html
     *
     * @param s 年代
     * @return {@link String}
     */
    public static String escape(String s) {

        StringBuilder out = new StringBuilder(s.length() + 128);

        for (int i = 0, length = s.length(); i < length; i++) {
            char c = s.charAt(i);

            /*
             * From RFC 4627, "All Unicode characters may be placed within the
             * quotation marks except for the characters that must be escaped:
             * quotation mark, reverse solidus, and the control characters
             * (U+0000 through U+001F)."
             */
            switch (c) {
                case '"':
                case '\\':
                case '/':
                    out.append('\\').append(c);
                    break;

                case '\t':
                    out.append("\\t");
                    break;

                case '\b':
                    out.append("\\b");
                    break;

                case '\n':
                    out.append("\\n");
                    break;

                case '\r':
                    out.append("\\r");
                    break;

                case '\f':
                    out.append("\\f");
                    break;

                default:
                    if (c <= 0x1F) {
                        out.append(String.format("\\u%04x", (int) c));
                    } else {
                        out.append(c);
                    }
                    break;
            }

        }

        return out.toString();
    }


    /**
     * 得到文件目录
     *
     * @return {@link File}
     */
    public static File getMarkdownFilesDir(Context context) {
        return FileUtils.getDir(context.getExternalFilesDir("MarkdownFiles"));
    }

    /**
     * 得到资源目录
     *
     * @return {@link File}
     */
    public static File getResourcesDir(Context context) {
        return FileUtils.getDir(context.getExternalFilesDir("Resources"));
    }

    /**
     * 得到src dir
     *
     * @param context 上下文
     * @return {@link File}
     */
    public static File getSrcDir(Context context) {
        return FileUtils.getDir(context.getExternalFilesDir("Src"));
    }
    /**
     * 得到src dir
     *
     * @param context 上下文
     * @return {@link File}
     */
    public static File getFontDir(Context context) {
        return FileUtils.getDir(context.getExternalFilesDir("Font"));
    }


    /**
     * 得到文件目录
     *
     * @return {@link File}
     */
    public static File getRecoveryDir(Context context) {
        return FileUtils.getDir(new File(context.getExternalCacheDir(), "Recovery"));
    }

    /**
     * 得到文件目录
     *
     * @return {@link File}
     */
    public static File getTmpHtmlDir(Context context) {
        return FileUtils.getDir(new File(context.getExternalCacheDir(), "Html"));
    }


    /**
     * 得到缓存目录
     *
     * @return {@link File}
     */
    public static File getTmpDir(Context context) {
        return FileUtils.getDir(new File(context.getExternalCacheDir(), "tmp"));
    }

}
